package com.liz.lizrpccore.lizspring;

import com.liz.lizrpccore.annotations.LizRpcComponentScan;
import com.liz.lizrpccore.lizspring.postprocessor.CustomerResourceAnnotationBeanPostProcessor;
import com.liz.lizrpccore.lizspring.postprocessor.CustomerResourceAnnotationBeanPostProcessorBack;
import com.liz.lizrpccore.lizspring.postprocessor.ProviderServiceAnnotationBeanPostProcessor;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.*;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

import static org.springframework.beans.factory.support.BeanDefinitionBuilder.rootBeanDefinition;

/**
 * @author liangGongWei
 * @description
 * @create 2022-04-11 17:27
 **/

public class LizRpcComponentScanRegistrar implements ImportBeanDefinitionRegistrar {


    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        AnnotationAttributes mapperScanAttrs = AnnotationAttributes
                .fromMap(importingClassMetadata.getAnnotationAttributes(LizRpcComponentScan.class.getName()));
        String basePackage = mapperScanAttrs.getString("basePackage");
        if (basePackage == null) {
            return;
        }
        registerServiceAnnotationBeanPostProcessor(basePackage, registry);
        registerReferenceAnnotationBeanPostProcessor(registry);
    }


    /**
     * 这个方法注册了 ProviderServiceAnnotationBeanPostProcessor 用于找到 带有providerService注解的类，将其注册到spring上下文中
     */
    private void registerServiceAnnotationBeanPostProcessor(String basePackages, BeanDefinitionRegistry registry) {
        BeanDefinitionBuilder builder = rootBeanDefinition(ProviderServiceAnnotationBeanPostProcessor.class);
        builder.addConstructorArgValue(basePackages);
        builder.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);

    }

    /**
     * 在spring bean初始化前 通过 postProcessBeforeInitialization方法  将带有customerResource注解属性，spring 的bean的属性中
     */
    private void registerReferenceAnnotationBeanPostProcessor(BeanDefinitionRegistry registry) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(CustomerResourceAnnotationBeanPostProcessor.class);
        beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        registry.registerBeanDefinition(CustomerResourceAnnotationBeanPostProcessor.BEAN_NAME, beanDefinition);
    }

}
